#include<iostream>
#include<string>
#include "class_learn.h"

struct Foo {
    int x{};
    int y{};
};

class Foo1 {
    int m_x{};
    int m_y{};
};

class Something {
    private:
        int m_x{};
        int m_y{};
    public:
        Something() {
            m_x = 6;
            m_y = 7;
        }

        int getX() const { return m_x; } // const
        
};

void class_construct() {
    Foo foo{6, 7}; // 使用聚合初始化

    // Foo1 foo1{6, 7}; // 编译失败；不能使用聚合初始化

    const Something s{}; // const 对象, 隐式调用 (non-const) 构造函数

    std::cout << s.getX(); // 打印 5
}

class Init1 {
    private:
        int m_x{};
        int m_y{};
    public:
        Init1(int x, int y) 
        // C++标准是这样说的，所有成员初始化列表中的成员总是按照它们在类中定义的顺序进行初始化（而不是按照列表中定义的次序）
        // 由于m_x在类定义中定义在m_y之前，因此m_x将首先初始化（即使它没有在列表中首先列出）
        : m_x{x}, m_y{y} // 这里是 成员初始化列表
        {
            std::cout << "Init1()" << std::endl;
        }

        void print() const {
            std::cout << "x: " << m_x << " y: " << m_y << std::endl;
        }
};
void class_construct_list() {
    Init1 init1{6, 7}; // 显式调用构造函数
    init1.print();
}

class Init2 {
    private:
        int m_x{}; // 默认成员初始值 (会被忽略)
        int m_y{2}; // 默认成员初始值 (被使用)
        int m_z{}; // 无默认值
    public:
        Init2(int x) 
        : m_x{x} // 这里是 成员初始化列表
        {
            std::cout << "Init2()" << std::endl;
        }

        void print() const {
            std::cout << "x: " << m_x << " y: " << m_y << std::endl;
        }
};

void class_construct_list2() {
    Init2 init2{6}; // 显式调用构造函数
    init2.print(); // 打印Init2(6, 2, -858993460)
}


class Fraction {
    private:
        int m_numerator{};
        int m_denominator{};
    public:
        Fraction(int numerator, int denominator) 
        : m_numerator{numerator}, m_denominator{denominator}
        {
            std::cout << "Fraction()" << std::endl;
        }

        // 显示定义copy函数
        Fraction(const Fraction& fraction)
        : m_numerator{fraction.m_numerator}, m_denominator{fraction.m_denominator}
        {
            std::cout << "Fraction(const Fraction&)" << std::endl;
        }

        void print() const {
            std::cout << m_numerator << "/" << m_denominator << std::endl;
        }
};

void class_copy_func() {
    Fraction f1{6, 7};
    Fraction f2{f1}; // 显式调用拷贝构造函数
    f2.print();
}